//    equip.c

#include <dbase.h>
#include <weapon.h>

int wear()
{
    object owner;
    mapping armor_prop, applied_prop;
    string *apply, type;

    // Only character object can wear armors.
    owner = environment();
    if (! owner || ! owner->is_character()) return 0;

        // Does the consistence valid ?
        if (query("consistence") < 1)
                return notify_fail(this_object()->name() + "现在损坏太严重了，不能继续穿戴了。\n");

    // If already worn, just recognize it.
    if (query("equipped")) return 1;

        // If handing it now, stop handing
        if (owner->query_temp("handing") == this_object())
                owner->delete_temp("handing");

    // Check if we have "armor_prop" defined.
    if (! mapp(armor_prop = query("armor_prop")) ||
            ! stringp(type = query("armor_type")))
        return notify_fail("你只能穿戴可当作护具的东西。\n");

    if (owner->query_temp("armor/" + type))
        return notify_fail("你已经穿戴了同类型的护具了。\n");

    owner->set_temp("armor/" + type, this_object());
    apply = keys(armor_prop);
    applied_prop = owner->query_temp("apply");
    if (! mapp(applied_prop)) applied_prop = ([]);
    for(int i = 0; i<sizeof(apply); i++)
        if (undefinedp(applied_prop[apply[i]]))
            applied_prop[apply[i]] = armor_prop[apply[i]];
        else
            applied_prop[apply[i]] += armor_prop[apply[i]];
    owner->set_temp("apply", applied_prop);
    set("equipped", "worn");
    return 1;
}

int wield()
{
    object owner, old_weapon;
    mapping weapon_prop;
    string *apply/*, type*/;
        mixed no_wield;
    int flag;

    // Only character object can wear armors.
    owner = environment();
    if (! owner || ! owner->is_character()) return 0;

        // Does the consistence valid ?
        if (query("consistence") < 1)
                return notify_fail(this_object()->name() + "现在损坏太严重了，不能继续装备了。\n");

    // If already wielded, just recognize it.
    if (query("equipped")) return 1;

        // If the item can not wield, I will return the fail message
        if (no_wield = query("no_wield"))
        {
                // can not wield
                if (stringp(no_wield))
                        return notify_fail(no_wield);
                else
                        return notify_fail("这样东西无法装备。");
        }

        // If handing it now, stop handing
        if (owner->query_temp("handing") == this_object())
                owner->delete_temp("handing");

    // Check if we have "weapon_prop" defined.
    if (! mapp(weapon_prop = query("weapon_prop")) ||
            ! stringp(query("skill_type")))
        return notify_fail("你只能装备可当作武器的东西。\n");

    flag = query("flag");

    if (flag & TWO_HANDED)
    {
        if(owner->query_temp("secondary_weapon") ||
           owner->query_temp("weapon") ||
                   owner->query_temp("handing"))
            return notify_fail("你必须空出双手才能装备该武器。\n");
        owner->set_temp("weapon", this_object());
    } else
    {
        // If we are are using any weapon?
        if (! (old_weapon = owner->query_temp("weapon")))
            owner->set_temp("weapon", this_object());

        else // If we still have a free hand?
        if (!owner->query_temp("secondary_weapon")
                &&  !owner->query_temp("handing"))
        {
            // If we can wield this as secondary weapon?
                      if(flag & SECONDARY) {
                owner->set_temp("secondary_weapon", this_object());
                        }
            // If we can switch our old weapon to secondary weapon ?
            else if( (int)old_weapon->query("flag") & SECONDARY ) {
                old_weapon->unequip();
                owner->set_temp("weapon", this_object());
                old_weapon->wield();

            // We need unwield our old weapon before we can use this one.
            } else
                return notify_fail("你必须先放下你目前装备的武器。\n");

        // We have both hands wearing something.
        } else
            return notify_fail("你必须空出一只手来使用武器。\n");
    }

        // add by doing to discard the secondary_weapon's prop
        if (owner->query_temp("secondary_weapon") != this_object())
        {
            apply = keys(weapon_prop);
            for(int i = 0; i<sizeof(apply); i++)
                owner->add_temp("apply/" + apply[i], weapon_prop[apply[i]]);
        }

    owner->reset_action();
    set("equipped", "wielded");
    return 1;
}

int unequip()
{
    object owner;
    mapping prop = 0, applied_prop;
    string *apply, equipped;

    if (! (owner = environment())->is_character())
        return 0;

    if (! stringp(equipped = query("equipped")))
        return notify_fail("你目前并没有装备这样东西。\n");

    if (equipped == "wielded")
    {
        if ((object)owner->query_temp("weapon") == this_object())
                {
                prop = query("weapon_prop");
            owner->delete_temp("weapon");
        } else
        if ((object)owner->query_temp("secondary_weapon") == this_object())
                {
            owner->delete_temp("secondary_weapon");
                        prop = 0;
                }
        owner->reset_action();
    } else
    if (equipped == "worn")
    {
        owner->delete_temp("armor/" + query("armor_type"));
        prop = query("armor_prop");
    }

        if (mapp(prop))
        {
            apply = keys(prop);
            applied_prop = owner->query_temp("apply");
            for (int i = 0; i<sizeof(apply); i++)
                // To support array apply, we cannot add_temp() here.
                applied_prop[apply[i]] -= prop[apply[i]];
        }

    delete("equipped");
    return 1;
}

// hit the object as a weapon
mixed hit_ob(object me, object victim, int damage_bonus)
{
        mixed foo;

        foo = this_object()->weapon_hit_ob(me, victim, damage_bonus);

        ITEM_D->reduce_consistence(this_object());

        if (! mapp(query_temp("daub")))
                return foo;

        COMBAT_D->hit_with_poison(me, victim, this_object());
        return foo;
}

// other one hit me as an armor
mixed valid_damage(object me, object victim, int damage_bonus)
{
        ITEM_D->reduce_consistence(this_object());

        if (! mapp(query_temp("daub")))
                return;

        if (me->query_temp("weapon") || me->query_temp("remote_attack") ||
        me->query("not_living"))
    {
                // the attacker has weapon, or remote attack, or not living,
        // he won't be poisoned by my cloth or armor
                return;
    }

        COMBAT_D->hit_poison(me, victim, this_object());
        return;
}
